<template>
	<view class="image-uploader">
		<uni-file-picker ref="filePicker" v-model="fileList" fileMediatype="image" mode="grid" limit="9"
			:auto-upload="false" @select="onSelect" @progress="onProgress" @success="onSuccess" @fail="onFail"
			@delete="onDelete">
			<template v-slot:header>
				<view class="upload-title">点击选择图片(最多9张)</view>
			</template>
		</uni-file-picker>

		<button type="primary" :loading="uploading" :disabled="fileList.length === 0 || uploading" @click="uploadAll">
			{{ uploading ? `上传中(${progress}%)` : "上传全部图片" }}
		</button>
	</view>
</template>

<script setup>
	import {
		ref
	} from "vue";
	import Compressor from "compressorjs";
	import {
		useAuthStore
	} from "@/stores/auth";
	const authStore = useAuthStore();

	const props = defineProps({
		// 上传接口地址
		apiUrl: {
			type: String,
			required: true
		},
		// 压缩质量 (0-1)
		quality: {
			type: Number,
			default: 0.8
		},
		// 最大宽度
		maxWidth: {
			type: Number,
			default: 1920
		},
		// 最大高度
		maxHeight: {
			type: Number,
			default: 1920
		}
	});

	const emit = defineEmits(["upload-success", "upload-error", "upload-progress"]);

	const filePicker = ref(null);
	const fileList = ref([]);
	const uploading = ref(false);
	const progress = ref(0);

	// 图片选择回调
	const onSelect = (e) => {
		console.log("选择文件:", e);
		fileList.value = e.tempFiles;
	};

	// 压缩图片
	const compressImage = (file) => {
		return new Promise((resolve, reject) => {
			new Compressor(file, {
				quality: props.quality,
				maxWidth: props.maxWidth,
				maxHeight: props.maxHeight,
				success(result) {
					resolve(result);
				},
				error(err) {
					reject(err);
				}
			});
		});
	};

	// 上传所有图片
	const uploadAll = async () => {
		if (fileList.value.length === 0) {
			uni.showToast({
				title: "请先选择图片",
				icon: "none"
			});
			return;
		}

		uploading.value = true;
		progress.value = 0;

		try {
			const formData = new FormData();
			const token = authStore.getToken();

			if (!token) {
				throw new Error("未登录，请先登录");
			}

			// 压缩所有图片并添加到FormData
			for (let i = 0; i < fileList.value.length; i++) {
				const file = fileList.value[i];
				try {
					const compressedFile = await compressImage(file.file);
					formData.append("file", compressedFile, file.name || `image_${Date.now()}_${i}.jpg`);
				} catch (err) {
					console.error("图片压缩失败:", err);
					// 压缩失败则上传原图
					formData.append("file", file.file, file.name || `image_${Date.now()}_${i}.jpg`);
				}

				// 更新进度
				progress.value = Math.floor(((i + 1) / fileList.value.length) * 100);
				emit("upload-progress", progress.value);
			}

			// 执行上传
			const result = await uploadFormData(formData, token);
			emit("upload-success", result);
			uni.showToast({
				title: "上传成功",
				icon: "success"
			});
			fileList.value = []; // 清空已上传文件
		} catch (error) {
			console.error("上传失败:", error);
			emit("upload-error", error);
			uni.showToast({
				title: error.message || "上传失败",
				icon: "none"
			});
		} finally {
			uploading.value = false;
			progress.value = 0;
		}
	};

	// 上传FormData
	const uploadFormData = (formData, token) => {
		return new Promise((resolve, reject) => {
			const xhr = new XMLHttpRequest();

			xhr.open("POST", props.apiUrl, true);
			xhr.setRequestHeader("Authorization", `Bearer ${token}`);

			xhr.upload.onprogress = (e) => {
				if (e.lengthComputable) {
					const percent = Math.floor((e.loaded / e.total) * 100);
					progress.value = percent;
					emit("upload-progress", percent);
				}
			};

			xhr.onload = () => {
				if (xhr.status >= 200 && xhr.status < 300) {
					try {
						const response = JSON.parse(xhr.responseText);
						resolve(response);
					} catch (e) {
						resolve(xhr.responseText);
					}
				} else {
					reject(new Error(`上传失败: ${xhr.statusText}`));
				}
			};

			xhr.onerror = () => {
				reject(new Error("网络错误，上传失败"));
			};

			xhr.send(formData);
		});
	};

	// 其他回调函数
	const onProgress = (e) => {
		console.log("上传进度:", e);
	};

	const onSuccess = (e) => {
		console.log("上传成功:", e);
	};

	const onFail = (e) => {
		console.error("上传失败:", e);
	};

	const onDelete = (e) => {
		console.log("删除文件:", e);
		fileList.value = fileList.value.filter((item) => item.uid !== e.tempFile.uid);
	};
</script>

<style scoped>
	.image-uploader {
		padding: 20rpx;
	}

	.upload-title {
		font-size: 28rpx;
		color: #666;
		padding: 10rpx 0;
	}
</style>